package com.kitty.game.activity.service.task;

import com.kitty.common.model.Pos;
import com.kitty.common.utils.SpringUtils;
import com.kitty.common.utils.ConcurrentHashSet;
import com.kitty.game.activity.model.product.ActivityType;
import com.kitty.game.activity.model.user.RoleTowerData;
import com.kitty.game.activity.service.ActivityService;
import com.kitty.game.boss.BossDataPool;
import com.kitty.game.boss.model.BossNpcParam;
import com.kitty.game.chat.service.ChatService;
import com.kitty.game.config.NPC;
import com.kitty.game.config.TaskSet;
import com.kitty.game.config.XinJun;
import com.kitty.game.confirm.model.GiveUpTaskConfirm;
import com.kitty.game.confirm.model.TowerChangeRewardConfirm;
import com.kitty.game.confirm.model.TowerFlyUpConfirm;
import com.kitty.game.confirm.model.TowerTeamFlyUpConfirm;
import com.kitty.game.enter.ReqTelePort;
import com.kitty.game.enter.RespDisappear;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.factory.FightFactory;
import com.kitty.game.map.service.MapService;
import com.kitty.game.npc.message.RespNpcContent;
import com.kitty.game.npc.model.NpcButton;
import com.kitty.game.npc.service.NewNpcService;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.rank.model.record.TowerMirrorRankRecord;
import com.kitty.game.rank.service.handler.TowerMirrorRankHandler;
import com.kitty.game.rank.service.handler.TowerRankHandler;
import com.kitty.game.role.model.Role;
import com.kitty.game.task.message.vo.TaskInfo;
import com.kitty.game.task.model.product.TaskType;
import com.kitty.game.team.message.RespConfirm;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.team.model.Member;
import com.kitty.game.team.model.Team;
import com.kitty.game.utils.AsktaoUtil;
import com.kitty.game.utils.Const;
import com.kitty.listener.event.FightEndEvent;
import com.kitty.common.model.Reason;
import com.kitty.mina.cache.SessionCache;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.MessagePusher;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.session.IoSession;
import org.nutz.lang.util.NutMap;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.concurrent.ThreadLocalRandom;
//后加
import com.kitty.game.tongtianta.BallotInfo;
import com.kitty.game.tongtianta.RespBallotResult;
import com.kitty.game.tongtianta.RespFeiSheng;
import com.kitty.game.tongtianta.RespTeamBallot;
import com.kitty.game.tongtianta.RespTongTianTaBonus;
import com.kitty.game.tongtianta.RespTongTianTaInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
//import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**通天塔任务处理类*/
@Component
@Slf4j
public class TowerTaskHandler extends TaskActivityHandler {
    private static final int ACCEPT_MIN_LEVEL = 50;
    /**队员之间最大等级差*/
    private static final int MAX_LEVEL_DIFF = 10;
    /**星君NPC id列表*/
    private static final List<Integer> XIN_JUN_NPCID_LIST = Arrays.asList(19974, 19975, 19976, 19977, 19979, 19980, 19981);

    /**通天塔第1个任务ID*/
    private static final int FIRST_TASK_ID = 83;

    /**初始时的层数与角色等级的差值*/
    private static final int INIT_LEVEL_DIFF = 11;
    /*通天塔层数*/
    private static final int MAX_LAYER = 200;

    private static final int TOWER_MAPID = 37000;
    private static final int TOWER_ENTER_X = 31;
    private static final int TOWER_ENTER_Y = 24;

    private static final int EXIT_TOWER_MAPID = 5000;
    private static final int EXIT_TOWER_X = 110;
    private static final int EXIT_TOWER_Y = 15;
    /**飞升最少的层数*/
    private static final int MIN_FLY_COUNT = 2;
    /**使用金钱飞升最多的层数*/
    private static final int MAX_FLY_COUNT_USING_MONEY = 5;
    /**使用元宝飞升最多的层数*/
    private static final int MAX_FLY_COUNT_USING_GOLD = 10;
    /**加入排行榜的 最小突破次数*/
    private static final int RANK_MIN_BREAK_COUNT = 10;
    /**发谣言的突破层数*/
    private static final int HUMOR_BREAK_LAYER_COUNT = 20;

    private static final String LEVEL_NOT_ENOUGH = "你的修为尚浅，恐难解天意，等等级提升至" + ACCEPT_MIN_LEVEL + "后再来找我吧！[离开]";
    private static final String REMAIN_COUNT_NOT_ENOUGH = "今日通天塔任务已完成！[离开]";
    private static final String CHOOSE_REWARD = "挑战通天塔可以获得两种奖励。你希望获得什么奖励？[经验奖励/"+ NpcButton.CHOOSE_TOWER_REWARD_EXP.getKey() +"][道行奖励/"+ NpcButton.CHOOSE_TOWER_REWARD_DAOHNAG.getKey() +"][我不想去了/离开]";

    private static final String TEAM_REMAIN_COUNT_NOT_ENOUGH = "队伍中的#Y{0}#n今日通天塔任务已完成，无法组队进入通天塔。[离开]";
    private static final String TEAM_NOT_ACCEPTED = "队伍中的#Y{0}#n还未领取通天塔任务，先暂离去领取任务后再来吧！[离开]";
    private static final String LEVEL_NOT_ENOUGH_TEAM = "队伍中#Y{0}#n等级<{1}级，无法进入通天塔。[离开]";
    private static final String FIGHT_LAYER_NOT_SAME = "队伍中的#Y{0}#n与队长需要挑战的层数不同，无法组队进入通天塔。[离开]";
    private static final String FIGHT_STAGE_NOT_SAME = "队伍中的#Y{0}#n与队长需要挑战的挑战阶段不同，无法组队进入通天塔。[离开]";
    private static final String TEAM_LEVEL_DIFF_MORE = "队伍中的成员的最大等级差超过了#R{0}级#n，无法组队进入通天塔！[离开]";
    private static final String TEAM_CURRENT_NOT_FINISH = "队伍中的#Y{0}#n未通过本层的挑战，无法组队进入通天塔。[离开]";
    private static final String TEAM_FLY_UP_BEYOND_REFINE = "队伍中的#Y{0}#n飞升后跨越目标层数，无法组队进入通天塔。[离开]";
    private static final String TEAM_MEMBER_LEAVE = "队伍中的#Y{0}#n暂离，无法组队进入通天塔。[离开]";

    private static final String CONTENT = "吾奉天命，在此传教天道之根本，汝须用心参悟才是。[烦请星君多多指教/" + NpcButton.FIGHT_TO_XIN_JUN.getKey() + "][离开]";
    private static final String FAIL_CONTENT = "来日方长，待道友重振旗鼓，再来见识通天塔之玄妙。[重新挑战/" + NpcButton.FIGHT_TO_XIN_JUN_RESTART.getKey() + "][离开]";
    private static final String WIN_CONTENT = "道友已参透此处玄机，佩服，佩服。[挑战下层/" + NpcButton.ENTER_NEXT_LAYER.getKey() + "][飞升/" + NpcButton.FLY_UP.getKey() + "][离开]";
    private static final String WIN_CONTENT2 = "道友已参透此处玄机，佩服，佩服。[挑战下层/" + NpcButton.ENTER_NEXT_LAYER.getKey() + "][离开]";
    private static final String CURRENT_NOT_FINISH = "修心悟道需讲究循序渐进，你尚未通过本层的挑战，无法进阶至更高的塔层。[离开]";
    private static final String FLY_UP_BEYOND_REFINE = "修炼阶段，飞升不可跨越目标层数。[离开]";
    private static final String TEAM_FLY_UP_CONSUME_TIP = "队长申请消耗#R{0}#n{1}，飞升至#R{2}#n层，是否同意？";
    private static final String FLY_UP_CONSUME_TIP = "是否消耗#R{0}#n{1}，飞升至#R{2}#n层？";
    private static final String TEAM_FLY_UP_RESOURCE_NOT_ENOUGH = "队伍中的#Y{0}#n的{1}不足，无法飞升！[离开]";
    private static final String TO_MAX_LAYER = "已经达到通天塔顶层！[离开]";
    private static final String RETURN_TEAM_NOT_IN_SAME_LAYER = "归队失败，需要与队长处在通天塔同一层才能归队。";

    private static final String CURRENT_LAYER_FINISH_TIP = "你已参透此处玄机，快前往下层继续挑战吧！";
    private static final String CURRENT_LAYER_START_TIP = "本层挑战的星君为#R{0}#n，快快前去挑战吧！";
    private static final String NOT_ACCEPTED = "你身上没有通天塔修炼任务。[离开]";
    private static final String CHANGE_REWARD_TIP = "你当前选择的奖励类型为{0}奖励，请确认是否需要修改为{1}奖励？";
    private static final String CHANGE_REWARD_IN_BREAK_STAGE = "你的实力不俗，已经到达突破挑战阶段，此阶段不可轻易更换奖励类型。[离开]";

    private static final String NOT_GIVE_UP_TASK_TIP_IN_TOWER = "在通天塔内不能放弃挑战。";
    private static final String NOT_ACCEPTED_TOWER_TASK = "未接取通天塔任务";
    private static final String GIVE_UP_TASK_IN_REFINE_STAGE = "放弃该任务，今日再次挑战将从初始层开始，是否确认放弃？";
    private static final String GIVE_UP_TASK_IN_BREAK_STAGE = "放弃该任务，今日不可再接取，是否确认放弃？";

    private static final String TASK_JIESHAO_REFINE_NOT_FINISH = "凡诚心向道者，皆可在通天塔内潜心修炼，领悟天道。\r\n当前正在进行的是#R通天塔修炼挑战阶段#n。\r\n挑战目标：在通天塔内完成#R第{0}层#n的挑战。\r\n当前挑战情况：在#R通天塔{1}层#n挑战#P{2}#P";
    private static final String TASK_JIESHAO_REFINE_FINISH = "凡诚心向道者，皆可在通天塔内潜心修炼，领悟天道。\r\n当前正在进行的是#R通天塔修炼挑战阶段#n。\r\n挑战目标：在通天塔内完成#R第{0}层#n的挑战。\r\n当前挑战情况：已完成本层的挑战，现在可以前往下一层了。";
    private static final String TASK_JIESHAO_BREAK_NOT_FINISH = "突破极限，挑战自我。\r\n当前正在进行的是#R通天塔突破挑战阶段#n。\r\n在该阶段下，每成功挑战一层就能获得一层的奖励。\r\n当前挑战情况：在#R通天塔{0}层#n挑战#P{1}#P。";
    private static final String TASK_JIESHAO_BREAK_FINISH = "突破极限，挑战自我。\r\n当前正在进行的是#R通天塔突破挑战阶段#n。\r\n在该阶段下，每成功挑战一层就能获得一层的奖励。\r\n当前挑战情况：已完成本层的挑战，现在可以前往下一层了。";

    private static final String TASK_ZHIYIN_NOT_FINISH = "挑战#P{0}|M=烦请星君多多指教@P北斗星使|M=【进塔】进入通天塔#P";
    private static final String TASK_ZHIYIN_FINISH = "前往#P通天塔{0}层|{1}|M=挑战下层@P北斗星使|M=【进塔】进入通天塔#P";

    /**突破超过层数后的谣言内容*/
    private static final String BREAK_MORE_NUMOR = "听闻#Y{0}#n在通天塔中大展雄风，成功额外挑战了#R{1}层#n的星君，真是实力超群啊！";


    /**选择进入通天塔*/
    public String doChooseEnterTower(Role role, NPC npc) {
        /**判断是否在队伍中*/
        boolean isInTeam = teamService.isInTeam(role);
        if (isInTeam == false) {
            /**个人*/
            return enterTowerForSingle(role);
        } else {
            /**组队*/
            Team team = teamService.getTeam(role.getRoleId());
            return enterTowerForTeam(role, team);
        }
    }

    /**个人进入通天塔*/
    private String enterTowerForSingle(Role role) {
        if (!isAcceptedTask(role)) {
            String check = checkEnterTowerForSingle(role);
            if (check != null) {
                return check;
            }

            return CHOOSE_REWARD;
        }

        doEnterTower(role);

        return null;
    }

    /**检测个人进入通天塔条件是否满足*/
    private String checkEnterTowerForSingle(Role role) {
        if (role.getLevel() < ACCEPT_MIN_LEVEL) {
            return LEVEL_NOT_ENOUGH;
        }
        boolean haveRemainCount = SpringUtils.getBean(ActivityService.class).isHaveRemainCount(role, ActivityType.TOWER_TASK);
        if (haveRemainCount == false) {
            return REMAIN_COUNT_NOT_ENOUGH;
        }

        return null;
    }

    /**执行进入通天塔操作*/
    private void doEnterTower(Role role) {
        /**获得进入的位置*/
        ReqTelePort reqTelePort = new ReqTelePort();
        reqTelePort.setMapId(TOWER_MAPID);
        reqTelePort.setX(TOWER_ENTER_X);
        reqTelePort.setY(TOWER_ENTER_Y);
        SpringUtils.getMapService().changeMap(role, reqTelePort);

        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            teamService.memberHandle(team, (Role memberRole) -> {
                pushTowerInfo(memberRole);
                addRole(memberRole.getActivity().getRoleTowerData().getCurrentLayer(), memberRole);
                MessagePusher.pushMessage(memberRole, new RespMsg(MessageFormat.format(CURRENT_LAYER_START_TIP, memberRole.getActivity().getRoleTowerData().getCurrentXinJun())));
            });
        } else {
            pushTowerInfo(role);
            addRole(role.getActivity().getRoleTowerData().getCurrentLayer(), role);
            MessagePusher.pushMessage(role, new RespMsg(MessageFormat.format(CURRENT_LAYER_START_TIP, role.getActivity().getRoleTowerData().getCurrentXinJun())));
        }
    }

    private void pushTowerInfo(Role role) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();

        /**更新通天塔任务数据*/
        RespTongTianTaInfo respTongTianTaInfo = new RespTongTianTaInfo();
        respTongTianTaInfo.setCurLayer((short) (roleTowerData.getCurrentLayer()));
        respTongTianTaInfo.setBreakLayer(role.getLevel());
        if (roleTowerData.isCurrentFinish()) {
            respTongTianTaInfo.setCurType((byte)2);
        }
        respTongTianTaInfo.setNpcName(roleTowerData.getCurrentXinJun());
        /**显示奖励类型*/
        if (roleTowerData.getRewardType() == RoleTowerData.REWARD_EXP) {
            respTongTianTaInfo.setBonusType("exp");
        } else if (roleTowerData.getRewardType() == RoleTowerData.REWARD_DAOHANG) {
            respTongTianTaInfo.setBonusType("tao");
        }
        /**显示剩余次数*/
        if (roleTowerData.isInBreakStage() && roleTowerData.getFailCount() > 0) {
            respTongTianTaInfo.setCurType((byte) 3);
            respTongTianTaInfo.setChallengeCount((byte) (RoleTowerData.MAX_FAIL_COUNT - roleTowerData.getFailCount()));
        }

        MessagePusher.pushMessage(role, respTongTianTaInfo);
    }

    private void addRole(int num, Role role) {
        if (SessionCache.TONGTIANTAMAP.get(num) == null) {
            SessionCache.TONGTIANTAMAP.put(num, new ConcurrentHashSet<>());
        }
        // 消失上一层的外观
        log.info("名称={}=num={}", role.getName(), num);
        Set<Integer> set = SessionCache.TONGTIANTAMAP.get(num - 1);
        if (set != null) {
            log.info("上一层=num={}=大小={}", num - 1, set.size());
            for (Integer integer : set) {
                RespDisappear respDisappear = new RespDisappear();
                respDisappear.setId(integer);
                MessagePusher.pushMessage(role, respDisappear);
            }
        }

        // 进入下一层
        SessionCache.TONGTIANTAMAP.get(num).add(role.getRoleId());
    }

    /**选择通天塔奖励和进入通天塔*/
    public void chooseTowerRewardAndEnter(Role role, NPC npc, byte rewardType) {
        role.getTalk().pushChooseParam(Const.TOWER_REWARD_TYPE_KEY, rewardType);

        acceptTaskAtNpc(role, npc, false);
    }


    /**初始化玩家通天塔数据，在接取通天塔任务时调用*/
    private void initRoleTowerData(Role role) {
        RoleTowerData roleTowerData = new RoleTowerData();
        /**初始层数=玩家等级 - 差值 */
        int currentLayer = role.getLevel() - INIT_LEVEL_DIFF;
        roleTowerData.setCurrentLayer(currentLayer);
        /**随机挑战一个星君*/
        NPC randomXinJun = getRandomXinJun();
        roleTowerData.setCurrentXinJun(randomXinJun.getName());

        Byte rewardType = (Byte) role.getTalk().popChooseParam(Const.TOWER_REWARD_TYPE_KEY);
        roleTowerData.setRewardType(rewardType);
        roleTowerData.setStage(RoleTowerData.STAGE_REFINE);

        role.getActivity().setRoleTowerData(roleTowerData);
        role.save();
    }

    private NPC getRandomXinJun() {
        int index = ThreadLocalRandom.current().nextInt(XIN_JUN_NPCID_LIST.size());
        int npcId = XIN_JUN_NPCID_LIST.get(index);
        return SpringUtils.getBean(MapService.class).getNpc(npcId);
    }

    @Override
    public NPC getNpc(Role role, TaskSet taskSet) {
        return SpringUtils.getBean(MapService.class).getNpcByName(role.getActivity().getRoleTowerData().getCurrentXinJun());
    }

    /**组队进入通天塔*/
    private String enterTowerForTeam(Role role, Team team) {
        /**检测条件是否满足*/
        String check = checkEnterTowerForTeam(role, team);
        if (check != null) {
            return check;
        }

        /**进入通天塔操作*/
        doEnterTower(role);

        return null;
    }

    /**检测组队进入通天塔是否满足条件*/
    private String checkEnterTowerForTeam(Role role, Team team) {
        /**不是队长时，不能操作*/
        if (team.isLeader(role.getRoleId()) == false) {
            /**这里返回空字符串方便判断是否不能操作*/
            return "";
        }

        String names = null;
        /**判断是否有成员已经完成任务*/
        names = teamService.checkMember(team, (Role memberRole) -> SpringUtils.getBean(ActivityService.class).isHaveRemainCount(memberRole, ActivityType.TOWER_TASK) == false);
        if (names != null) {
            return MessageFormat.format(TEAM_REMAIN_COUNT_NOT_ENOUGH, names);
        }

        /**判断是否有成员未接取任务*/
        names = teamService.checkMember(team, (Role memberRole) -> isAcceptedTask(memberRole) == false);
        if (names != null) {
            return MessageFormat.format(TEAM_NOT_ACCEPTED, names);
        }

        /**判断是否有队员挑战层数不一致*/
        names = teamService.checkMember(team, (Role memberRole) -> isTowerLayerSame(role, memberRole) == false);
        if (names != null) {
            return MessageFormat.format(FIGHT_LAYER_NOT_SAME, names);
        }

        /**判断是否有队员所在阶段不一致*/
        names = teamService.checkMember(team, (Role memberRole) -> isTowerStageSame(role, memberRole) == false);
        if (names != null) {
            return MessageFormat.format(FIGHT_STAGE_NOT_SAME, names);
        }

        /**判断是否有队员等级不足*/
        names = teamService.checkMember(team, (Role memberRole) -> memberRole.getLevel() < ACCEPT_MIN_LEVEL);
        if (names != null) {
            return MessageFormat.format(LEVEL_NOT_ENOUGH_TEAM, names, ACCEPT_MIN_LEVEL);
        }

        /**判断是否有成员之前等级差超过限制*/
        names = teamService.checkMember(team, (Role memberRole) -> isRoleLevelDiffMore(team, memberRole));
        if (names != null) {
            return MessageFormat.format(TEAM_LEVEL_DIFF_MORE, MAX_LEVEL_DIFF);
        }

        names = teamService.getNotInTeam(team);
        if (names != null) {
            return MessageFormat.format(TEAM_MEMBER_LEAVE, names);
        }

        return null;
    }

    /**是否已经接取通天塔任务*/
    private boolean isAcceptedTask(Role role){
        return getTaskSetByType(role) != null;
    }

    /**是否两人的挑战层数一致*/
    private boolean isTowerLayerSame(Role role, Role memberRole) {
        if (role.getActivity().getRoleTowerData() != null && memberRole.getActivity().getRoleTowerData() != null) {
            return role.getActivity().getRoleTowerData().getCurrentLayer() == memberRole.getActivity().getRoleTowerData().getCurrentLayer();
        }

        return false;
    }

    /**是否两人的挑战阶段一致*/
    private boolean isTowerStageSame(Role role, Role memberRole) {
        if (role.getActivity().getRoleTowerData() != null && memberRole.getActivity().getRoleTowerData() != null) {
            return role.getActivity().getRoleTowerData().getStage() == memberRole.getActivity().getRoleTowerData().getStage();
        }

        return false;
    }

    /**是否成员之前等级差超过限制*/
    private boolean isRoleLevelDiffMore(Team team, Role memberRole) {
        return teamService.checkMember(team, (Role role) -> memberRole.getLevel() - role.getLevel() > MAX_LEVEL_DIFF) != null;
    }

    @Override
    public TaskSet getAcceptingTask(Role role, NPC npc) {
        return taskService.getTaskSet(FIRST_TASK_ID, role);
    }

    @Override
    public String canAcceptTask(Role role, TaskSet taskSet, boolean auto) {
        /**判断是否已经接取，正常都是未接取，避免抓包*/
        if (isAcceptedTask(role)) {
            return "";
        }

        return checkEnterTowerForSingle(role);
    }

    @Override
    public void doBeforeAccept(Role role, TaskSet taskSet) {
        initRoleTowerData(role);
    }

    @Override
    public void doAfterAccept(Role role, TaskSet taskSet) {
        super.doAfterAccept(role, taskSet);

        doEnterTower(role);
    }

    @Override
    public void handleLogin(Role role) {
        /**登录时如果在通天塔且不在战斗中(避免出现战斗重连时出现在塔外)，则退出通天塔*/
        if (isInTower(role) && SpringUtils.getFightService().isInFight(role) == false) {
            leave(role);
        }

        super.handleLogin(role);
    }

    @Override
    public TaskInfo getTaskInfo(Role role, TaskSet taskSet) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        String zhiying = getTaskZhiYin(role, taskSet);
        String jieshao = getTaskJieShao(role, taskSet);
        TaskInfo taskInfo = new TaskInfo();
        taskInfo.setTaskName(taskSet.getTaskName());
        if (roleTowerData.getRewardType() == RoleTowerData.REWARD_EXP) {
            taskInfo.setShow_name("通天塔（经验奖励）");
        } else {
            taskInfo.setShow_name("通天塔（道行奖励）");
        }
        taskInfo.setTaskInfo(jieshao);
        taskInfo.setTaskZhiyin(zhiying);
        taskInfo.setTaskJiangli(taskSet.getTaskGift());
        taskInfo.setQuit((short) taskSet.getGiveUp());// 是否可以放弃
        return taskInfo;
    }

    private String getTaskJieShao(Role role, TaskSet taskSet) {
        String content = null;
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (roleTowerData.isInBreakStage()) {
            content = roleTowerData.isCurrentFinish() ? TASK_JIESHAO_BREAK_FINISH : TASK_JIESHAO_BREAK_NOT_FINISH;
            content = MessageFormat.format(content, roleTowerData.getCurrentLayer(), roleTowerData.getCurrentXinJun());
        } else {
            content = roleTowerData.isCurrentFinish() ? TASK_JIESHAO_REFINE_FINISH : TASK_JIESHAO_REFINE_NOT_FINISH;
            content = MessageFormat.format(content, role.getLevel(), roleTowerData.getCurrentLayer(), roleTowerData.getCurrentXinJun());
        }
        return content;
    }

    private String getTaskZhiYin(Role role, TaskSet taskSet) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (roleTowerData.isCurrentFinish()) {
            return MessageFormat.format(TASK_ZHIYIN_FINISH, roleTowerData.getCurrentLayer()+1, roleTowerData.getCurrentXinJun());
        } else {
            return MessageFormat.format(TASK_ZHIYIN_NOT_FINISH, roleTowerData.getCurrentXinJun());
        }
    }

    @Override
    public String getPrompt(NPC npc) {
        return null;
    }

    @Override
    public BossNpcParam newBossNpcParam(Role role, TaskSet taskSet) {
        return null;
    }

    @Override
    public String getNpcContent(Role role, NPC bossNpc) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (roleTowerData.isCurrentFinish()) {
            /**当前层已经挑战成功*/
            return WIN_CONTENT2;
        } else {
            /**当前层未挑战成功*/
            String name = role.getActivity().getRoleTowerData().getCurrentXinJun();
            if (bossNpc.getName().equals(name)) {
                return CONTENT;
            } else {
                return bossNpc.getContent().replace(bossNpc.getName(), name);
            }
        }
    }

    @Override
    public TaskType getTaskType() {
        return TaskType.TOWER;
    }

    @Override
    public String getNpcContentNotFight(Role role, NPC bossNpc) {
        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            return checkEnterTowerForTeam(role, team);
        } else {
            return checkEnterTowerForSingle(role);
        }
    }

    @Override
    public void doStartFight(Role role, TaskSet taskSet, NPC bossNpc) {
        int fightType = getFightType(role);
        Fight battleground = FightFactory.getFightFactory(fightType).create(0, role, taskSet, bossNpc);
        battleground.start();
    }

    @Override
    public void doFightFail(Role role, TaskSet taskSet, FightEndEvent fightEndEvent) {
        super.doFightFail(role, taskSet, fightEndEvent);

        teamService.memberHandleThreadLocal(role, memberRole -> doFightFailSingle(memberRole, taskSet));
    }

    private void doFightFailSingle(Role role, TaskSet taskSet) {
        boolean add = addFailCount(role, taskSet);
        if (add && role.getActivity().getRoleTowerData().getFailCount() >= RoleTowerData.MAX_FAIL_COUNT) {
            /**完成任务*/
            setTaskFinish(role, taskSet);
            return ;
        }

        /**更新剩余次数*/
        pushTowerInfo(role);

        String name = role.getActivity().getRoleTowerData().getCurrentXinJun();
        NPC npc = SpringUtils.getMapService().getNpcByName(name);
        RespNpcContent respNpcContent = SpringUtils.getNpcService().getRespNpcContent(role, npc, FAIL_CONTENT);
        MessagePusher.pushMessage(role, respNpcContent);
    }

    /**设置任务完成*/
    private void setTaskFinish(Role role, TaskSet taskSet) {
        /**在通天塔时，离开通天塔*/
        if (isInTower(role)) {
            leave(role);
        }

        /**增加次数*/
        addActivityFinishCount(role, taskSet);

        /**删除任务*/
        deleteTaskForSingle(role, taskSet);

        /**完成时离队*/
        teamService.leave(role,false);

        /**完成任务时清空通天塔数据*/
        role.getActivity().setRoleTowerData(null);

        /**任务完成时，也判断是否发谣言*/
        pushNumor(role);

        role.save();
    }

    @Override
    public void doFightRunAway(Role role, TaskSet taskSet, FightEndEvent fightEndEvent) {
        super.doFightRunAway(role, taskSet, fightEndEvent);
        boolean add = addFailCount(role, taskSet);
        if (add && role.getActivity().getRoleTowerData().getFailCount() >= RoleTowerData.MAX_FAIL_COUNT) {
            /**完成任务*/
            setTaskFinish(role, taskSet);
            return ;
        }

        /**更新剩余次数*/
        pushTowerInfo(role);
    }

    /**增加失败次数*/
    private boolean addFailCount(Role role, TaskSet taskSet) {
        /**如果在突破阶段，则记录失败次数，达到最大失败次数，则完成任务，不再挑战*/
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (roleTowerData.isInBreakStage()) {
            roleTowerData.setFailCount(roleTowerData.getFailCount() + 1);
            role.save();

            return true;
        }
        return false;
    }

    /**是否在通天塔内*/
    private boolean isInTower(Role role) {
        return role.getPos().getMapId() == TOWER_MAPID;
    }

    /**是否在通天塔内*/
    private boolean isInTower(int mapId) {
        return mapId == TOWER_MAPID;
    }

    /**离开通天塔*/
    public void leave(Role role) {
        ReqTelePort reqTelePort = new ReqTelePort();
        reqTelePort.setMapId(EXIT_TOWER_MAPID);
        reqTelePort.setX(EXIT_TOWER_X);
        reqTelePort.setY(EXIT_TOWER_Y);
        SpringUtils.getMapService().changeMap(role, reqTelePort);

        if (role.getActivity().getRoleTowerData() != null) {
            int currentLayer = role.getActivity().getRoleTowerData().getCurrentLayer();
            delRole(currentLayer, role);
        }
    }

    private void delRole(int num, Role role) {
        if (SessionCache.TONGTIANTAMAP.get(num) != null) {
            SessionCache.TONGTIANTAMAP.get(num).remove(role.getRoleId());
        }
    }

    @Override
    public void doFightWinForSingle(Role role, TaskSet taskSet, FightEndEvent fightEndEvent) {
        /**不在通天塔内返回*/
        if (!isInTower(role)) {
            log.warn("战斗结束时，{}不在通天塔内。", role.getUid());
            return ;
        }
        setCurrentFinish(role);
        /**更新任务数据*/
        TaskInfo taskInfo = getTaskInfo(role, taskSet);
        taskService.pushTaskInfo(role, taskInfo);

        /**更新通天塔任务数据*/
        pushTowerInfo(role);

        if (role.getLevel() != role.getActivity().getRoleTowerData().getCurrentLayer()) {
            String name = role.getActivity().getRoleTowerData().getCurrentXinJun();
            NPC npc = SpringUtils.getMapService().getNpcByName(name);
            SpringUtils.getBean(NewNpcService.class).sendNpcContent(role, npc, WIN_CONTENT);
        }

        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        /**在突破阶段*/
        if (roleTowerData.isInBreakStage()) {
            /**发奖*/
            giveReward(role, fightEndEvent.getReward(), taskSet,fightEndEvent.getCurrPetId());

            /**发谣言*/
            pushNumor(role);

            /**判断突破阶段是否有失败过，有则完成任务*/
            if (roleTowerData.getFailCount() > 0) {
                setTaskFinish(role, taskSet);
            }
        }

        /**更新排行榜*/
        SpringUtils.getBean(TowerRankHandler.class).update(role, roleTowerData.getCurrentLayer());
    }

    /**突破层数超过一定数量时发谣言*/
    private void pushNumor(Role role) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (roleTowerData != null && roleTowerData.isInBreakStage() && roleTowerData.getCurrentLayer()-role.getLevel()>HUMOR_BREAK_LAYER_COUNT) {
            String msg = MessageFormat.format(BREAK_MORE_NUMOR, role.getName(), roleTowerData.getCurrentLayer()-role.getLevel());
            //SpringUtils.getBean(ChatService.class).sendNumor(msg, Const.BRODCAST_MSG_TYPE_ROLE);
        }
    }

    /**设置当前层已经挑战完成*/
    private void setCurrentFinish(Role role) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        roleTowerData.setCurrentFinish(true);
        MessagePusher.pushMessage(role, new RespMsg(CURRENT_LAYER_FINISH_TIP));

        if (roleTowerData.isInBreakStage() == false && roleTowerData.getCurrentLayer() >= role.getLevel()) {
            /**突破*/
            roleTowerData.setStage(RoleTowerData.STAGE_BREAK);

            /**突破时离队*/
            teamService.leave(role,false);
        }

        if (roleTowerData.isInBreakStage()) {
            addTowerRankData(role);
        }

        role.save();
    }

    public XinJun getXinjun(String name) {
        return BossDataPool.name2XingJun.get(name);
    }

    @Override
    protected int getFightType(Role role) {
        return Const.fightType_xinjun;
    }

    @Override
    protected void addActivityFinishCount(Role role, TaskSet taskSet) {
        SpringUtils.getBean(ActivityService.class).addFinishCount(role, ActivityType.TOWER_TASK, 1);
    }

    @Override
    protected void giveReward(Role role, NutMap reward, TaskSet taskSet,int currPetId) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        String name = roleTowerData.getCurrentXinJun();
        XinJun xinJun = getXinjun(name);
        IoSession session = SessionUtils.getSession(role.getRoleId());
        if (session == null) {
            return;
        }
        Role tempRole = SessionUtils.getRoleBySession(session);
        if (tempRole == null) {
            return;
        }
        switch (roleTowerData.getRewardType()) {
            case RoleTowerData.REWARD_EXP:
                int exp = calRewardValue(role, xinJun.getRewardExp());
                SpringUtils.getRoleService().addExp(role, exp, 1,currPetId);
                pushRewardInfo(role, exp);
                break;
            case RoleTowerData.REWARD_DAOHANG:
                int daohang = calRewardValue(role, xinJun.getRewardDaohang());
                addDaohang(role, xinJun.getRewardDaohang());
                pushRewardInfo(role, daohang);

                Pet pet = SpringUtils.getPetService().getPetById(role.getPetBox().getFightPetId(), role);
                if (pet != null) {
                    int petWuxue = calRewardValue(role, xinJun.getPetRewardWxue());
                    NutMap doubleStatus = role.getPropsStatus();
                    int point = doubleStatus.getInt("pet");
                    if (doubleStatus.getInt("petStatus") == 1 && point >= 4) {
                        doubleStatus.setv("pet", point - 4);
                        role.save();
                        petWuxue = petWuxue * 2;
                    }
                    SpringUtils.getRoleService().addPetMatiral(role, pet, petWuxue);
                }
                break;
        }
    }

    private int calRewardValue(Role role, int value) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (role.getLevel() == roleTowerData.getCurrentLayer()) {
            /**首次突破*/
            int initLevel = role.getLevel() - INIT_LEVEL_DIFF;
            int sum = 0;
            for (int i = initLevel; i < roleTowerData.getCurrentLayer(); i++) {
                sum  +=  value * i;
            }

            return sum;
        } else if (roleTowerData.getOldLayer() > 0 && roleTowerData.getCurrentLayer() > roleTowerData.getOldLayer()+1) {
            /**飞升*/
            int sum = 0;
            for (int i = roleTowerData.getOldLayer()+1; i < roleTowerData.getCurrentLayer(); i++) {
                sum += value * i;
            }
            return sum;
        } else {
            /**突破一层*/
            return value * roleTowerData.getCurrentLayer();
        }
    }

    /**增加道行*/
    private void addDaohang(Role role, int value) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        int count = 0;
        if (role.getLevel() == roleTowerData.getCurrentLayer()) {
            /**首次突破*/
            int initLevel = role.getLevel() - INIT_LEVEL_DIFF;
            for (int i = initLevel; i < roleTowerData.getCurrentLayer(); i++) {
                count  =  value * i;
                SpringUtils.getRoleService().addTao(role, count);
            }
        } else if (roleTowerData.getOldLayer() > 0 && roleTowerData.getCurrentLayer() > roleTowerData.getOldLayer()+1) {
            /**飞升*/
            for (int i = roleTowerData.getOldLayer()+1; i < roleTowerData.getCurrentLayer(); i++) {
                count = value * i;
                SpringUtils.getRoleService().addTao(role, count);
            }
        } else {
            /**突破一层*/
            count = value * roleTowerData.getCurrentLayer();
            SpringUtils.getRoleService().addTao(role, count);
        }
    }

    /**推送奖励信息到客户端*/
    private void pushRewardInfo(Role role, int value) {
        /**第1次突破时显示奖励界面*/
        if (role.getActivity().getRoleTowerData().isInBreakStage() && role.getLevel() == role.getActivity().getRoleTowerData().getCurrentLayer()) {
            RespTongTianTaBonus respTongTianTaBonus = new RespTongTianTaBonus();
            if (role.getActivity().getRoleTowerData().getRewardType() == RoleTowerData.REWARD_EXP) {
                respTongTianTaBonus.setBonusType("exp");
            } else {
                respTongTianTaBonus.setBonusType("tao");
            }
            respTongTianTaBonus.setBonusValue(value);
            MessagePusher.pushMessage(role, respTongTianTaBonus);
        }
    }

    /**进入下一层*/
    public void enterNextLayer(Role role, NPC npc) {
        /**检测能否进入下一层*/
        String check = checkEnterNextLayer(role);
        if (check != null) {
            if (npc != null) {
                SpringUtils.getNpcService().sendNpcContent(role, npc, check);
                return ;
            } else {
                MessagePusher.pushMessage(role, new RespMsg(check.replace(Const.LEAVE_BUTTON, "")));
                return ;
            }
        }

        /**下一层*/
        int nextLayer = role.getActivity().getRoleTowerData().getCurrentLayer() + 1;

        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            /**暂离玩家进行离队处理*/
            notInTeamLeave(team);

            teamService.memberHandle(team, (Role memberRole) -> {
                enterLayer(memberRole, nextLayer);
            });
        } else {
            enterLayer(role, nextLayer);
        }
    }

    /**检测能否进入下一层*/
    private String checkEnterNextLayer(Role role) {
        /**已经达到顶层时*/
        if (role.getActivity().getRoleTowerData().getCurrentLayer() >= MAX_LAYER) {
            return TO_MAX_LAYER;
        }

        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            /**判断是否有队员未通过本层挑战*/
            String names = teamService.checkMember(team, (Role memberRole) -> memberRole.getActivity().getRoleTowerData().isCurrentFinish() == false);
            if (names != null) {
                return MessageFormat.format(TEAM_CURRENT_NOT_FINISH, names);
            }

            /**进入检测*/
            String check = checkEnterTowerForTeam(role, team);
            if (check != null) {
                return check;
            }
        } else {
            /**判断是否未通过本层挑战*/
            if (role.getActivity().getRoleTowerData().isCurrentFinish() == false) {
                return CURRENT_NOT_FINISH;
            }

            /**进入检测*/
            String check = checkEnterTowerForSingle(role);
            if (check != null) {
                return check;
            }
        }

        return null;
    }

    /**暂离玩家进行离队处理*/
    private void notInTeamLeave(Team team) {
        /**遍历找到暂离玩家*/
        List<Role> notInTeamRoles = null;
        for (Member member : team.getList()) {
            if (member == null) {continue;}
            if (member.isInTeam() == true) {continue;}

            Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(member.getRoleId());
            if (memberRole == null) {continue;}

            if (notInTeamRoles == null) {
                notInTeamRoles = new ArrayList<>(2);
            }
            notInTeamRoles.add(memberRole);
        }

        /**对暂离玩家进行离队操作*/
        if (notInTeamRoles != null) {
            for (Role memberRole : notInTeamRoles) {
                teamService.leave(memberRole,false);
            }
        }
    }

    private void enterLayer(Role role, int layer) {
        setRoleTowerData(role, layer);
        doEnterLayer(role, layer);
    }

    private void setRoleTowerData(Role role, int layer) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        int oldLayer = roleTowerData.getCurrentLayer();
        roleTowerData.setOldLayer(oldLayer);

        /**更新当前层数为指定层*/
        roleTowerData.setCurrentLayer(layer);
        roleTowerData.setCurrentFinish(false);
        /**随机挑战一个星君*/
        NPC randomXinJun = getRandomXinJun();
        roleTowerData.setCurrentXinJun(randomXinJun.getName());

        /**设置任务的npc对象为新的星君*/
        NPC newNpc = SpringUtils.getBean(MapService.class).getNpcByName(role.getActivity().getRoleTowerData().getCurrentXinJun());
        role.getTask().addTaskNpcId(FIRST_TASK_ID, newNpc.getId());

        role.save();
    }

    /**进入通天塔层*/
    private void doEnterLayer(Role role, int layer) {
        /**从之前层移除，在指定层添加*/
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        delRole(roleTowerData.getOldLayer(), role);
        addRole(roleTowerData.getCurrentLayer(), role);

        /**进入地图时，传送到中间位置*/
        Pos pos = new Pos((short) TOWER_ENTER_X, (short) TOWER_ENTER_Y, (byte) 5, TOWER_MAPID);
        SpringUtils.getMapService().sendEnterMap(role, pos);

        /**显示NPC*/
        SpringUtils.getMapService().broadcastNpc(role, role.getPos().getMapId());

        /**更新任务数据*/
        TaskSet taskSet = getTaskSetByType(role);
        TaskInfo taskInfo = getTaskInfo(role, taskSet);
        taskService.pushTaskInfo(role, taskInfo);

        /**更新通天塔任务数据*/
       pushTowerInfo(role);

       /**当前层挑战对象提示*/
       MessagePusher.pushMessage(role, new RespMsg(MessageFormat.format(CURRENT_LAYER_START_TIP, roleTowerData.getCurrentXinJun())));
    }

    /**NPC处选择飞升，弹出选择飞升界面*/
    public void chooseFlyUp(Role role, NPC npc) {
        if (role.getActivity().getRoleTowerData().isCurrentFinish() == false) {
            /**当前层没有挑战通过时，不能飞升*/
            RespMsg respMsg = new RespMsg(CURRENT_NOT_FINISH);
            MessagePusher.pushMessage(role, respMsg);
            return ;
        }

        RespFeiSheng respFeiSheng = new RespFeiSheng();
        MessagePusher.pushMessage(role, respFeiSheng);
    }


    /**在飞升界面选择层数后*/
    public void flyUp(Role role, byte type, int flyUpCount) {
        /**修正跳的层数*/
        flyUpCount = getCorrectFlyUpCount(type, flyUpCount);

        /**判断能否飞升*/
        String check = checkFlyUp(role, flyUpCount);
        if (check != null) {
            RespMsg respMsg = new RespMsg(check.replace(Const.LEAVE_BUTTON, ""));
            MessagePusher.pushMessage(role, respMsg);
            return ;
        }


        if (type == Const.FLY_UP_TYPE_USING_MONEY) {
            flyUpUsingMoney(role, flyUpCount);
        } else if (type == Const.FLY_UP_TYPE_USING_GOLD) {
            flyUpUsingGold(role, flyUpCount);
        }
    }

    /**对飞升层数进行修正，避免抓包*/
    private int getCorrectFlyUpCount(byte flyUpType, int flyUpCount) {
        if (flyUpCount < MIN_FLY_COUNT) {return MIN_FLY_COUNT;}

        if (flyUpType == Const.FLY_UP_TYPE_USING_MONEY && flyUpCount > MAX_FLY_COUNT_USING_MONEY) {
            return MAX_FLY_COUNT_USING_MONEY;
        } else if (flyUpType == Const.FLY_UP_TYPE_USING_GOLD && flyUpCount > MAX_FLY_COUNT_USING_GOLD) {
            return MAX_FLY_COUNT_USING_GOLD;
        }

        return flyUpCount;
    }

    /**使用金钱飞升*/
    public void flyUpUsingMoney(Role role, int flyUpCount) {
        int money = getNeedMoney(flyUpCount);
        /**检测金钱是否满足*/
        if (role.getMoney() < money) {
            MessagePusher.pushMessage(role, new RespMsg(MessageFormat.format(Const.ROLE_RESOURCE_NOT_ENOUGH, Const.MONEY_NAME)));
            return ;
        }

        int jumpToLayer = role.getActivity().getRoleTowerData().getCurrentLayer() + flyUpCount;
        if (teamService.isInTeam(role)) {
            /**只有队长能操作*/
            if (teamService.isTeamLeader(role) == false) {return ;}
            Map<Integer, Short> ballotResults = new HashMap<>();
            role.setConfirm(new TowerTeamFlyUpConfirm(Const.FLY_UP_TYPE_USING_MONEY, flyUpCount, ballotResults));
            Team team = teamService.getTeam(role.getRoleId());
            teamService.memberHandle(team, (Role memberRole) -> {
                ballotResults.put(memberRole.getRoleId(), Const.BALLOT_TYPE_UN_OP);
            });
            ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_AGREEN);

            RespTeamBallot respTeamBallot = new RespTeamBallot();
            respTeamBallot.setTeamLeader(teamService.isTeamLeader(role));
            String msg = MessageFormat.format(TEAM_FLY_UP_CONSUME_TIP, AsktaoUtil.getMoneyFormat(money), "文"+Const.MONEY_NAME, jumpToLayer);
            respTeamBallot.setMsg(msg);
            respTeamBallot.setCurrTime(new Long(new Date().getTime() / 1000).intValue() + 30);
            String flyType = "金钱飞升投票";
            String flyString = "tongttjqfs";
            respTeamBallot.setTitle(flyType);
            respTeamBallot.setType(flyString);
            teamService.pushMessage(role, respTeamBallot);

            ArrayList<BallotInfo> ballotInfos = new ArrayList<>();
            BallotInfo ballotInfo = new BallotInfo();
            ballotInfo.setName(role.getName());
            ballotInfo.setType((short) 1);
            ballotInfos.add(ballotInfo);
            RespBallotResult respBallotResult = new RespBallotResult();
            respBallotResult.setMeTime((short) -1);
            respBallotResult.setResultList(ballotInfos);
            teamService.pushMessage(role, respBallotResult);
        } else {
            role.setConfirm(new TowerFlyUpConfirm(Const.FLY_UP_TYPE_USING_MONEY, flyUpCount));

            RespConfirm respConfirm = new RespConfirm();
            String msg = MessageFormat.format(FLY_UP_CONSUME_TIP, AsktaoUtil.getMoneyFormat(money), "文"+Const.MONEY_NAME, jumpToLayer);
            respConfirm.setTips(msg);
            respConfirm.setConfirm_type("");
            MessagePusher.pushMessage(role, respConfirm);
        }
    }
    /**获得飞升对应层数需要的金钱数量*/
    private int getNeedMoney(int flyUpCount) {
        /**使用金钱能跳2-5层*/
        if (flyUpCount < MIN_FLY_COUNT) {return 800000;}
        if (flyUpCount > MAX_FLY_COUNT_USING_MONEY) {return 3200000;}

        return (flyUpCount-1) * 800000;
    }

    /**使用元宝飞升*/
    public void flyUpUsingGold(Role role, int flyUpCount) {
        int gold = getNeedGold(flyUpCount);
        /**检测元宝是否满足*/
        if (role.getGold() < gold) {
            MessagePusher.pushMessage(role, new RespMsg(MessageFormat.format(Const.ROLE_RESOURCE_NOT_ENOUGH, Const.GOLD_NAME)));
            return ;
        }

        int jumpToLayer = role.getActivity().getRoleTowerData().getCurrentLayer() + flyUpCount;
        if (teamService.isInTeam(role)) {
            /**只有队长能操作*/
            if (teamService.isTeamLeader(role) == false) {return ;}
            Map<Integer, Short> ballotResults = new HashMap<>();
            role.setConfirm(new TowerTeamFlyUpConfirm(Const.FLY_UP_TYPE_USING_GOLD, flyUpCount, ballotResults));
            Team team = teamService.getTeam(role.getRoleId());
            teamService.memberHandle(team, (Role memberRole) -> {
                ballotResults.put(memberRole.getRoleId(), Const.BALLOT_TYPE_UN_OP);
            });
            ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_AGREEN);

            RespTeamBallot respTeamBallot = new RespTeamBallot();
            respTeamBallot.setTeamLeader(teamService.isTeamLeader(role));
            String msg = MessageFormat.format(TEAM_FLY_UP_CONSUME_TIP, AsktaoUtil.getMoneyFormat(gold), Const.GOLD_NAME, jumpToLayer);
            respTeamBallot.setMsg(msg);
            respTeamBallot.setCurrTime(new Long(new Date().getTime() / 1000).intValue() + 30);
            String flyType = "元宝飞升投票";
            String flyString = "tongttybfs";
            respTeamBallot.setTitle(flyType);
            respTeamBallot.setType(flyString);
            teamService.pushMessage(role, respTeamBallot);

            RespBallotResult respBallotResult = getRespBallotResult(role);
            teamService.pushMessage(role, respBallotResult);
            fixedTeamAutoAgreen(role,team);
        } else {
            role.setConfirm(new TowerFlyUpConfirm(Const.FLY_UP_TYPE_USING_GOLD, flyUpCount));

            RespConfirm respConfirm = new RespConfirm();
            String msg = MessageFormat.format(FLY_UP_CONSUME_TIP, AsktaoUtil.getMoneyFormat(gold), Const.GOLD_NAME, jumpToLayer);
            respConfirm.setTips(msg);
            respConfirm.setConfirm_type("");
            MessagePusher.pushMessage(role, respConfirm);
        }
    }
    /**
     * 投票。固定队开启自动同意投票
     */
    public void fixedTeamAutoAgreen(Role LeaderRole,Team team){
        //取队长固定队ID
        String fixedTeamId = LeaderRole.getFixedTeam();
        if(StringUtils.isNotEmpty(fixedTeamId)){
            for (Member member : team.getList()) {
                Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(member.getUid());
                if(!teamService.isTeamLeader(member.getRoleId())){
                    //如果是一个固定队
                    if(fixedTeamId.equals(memberRole.getFixedTeam())){
                        //自动同意
                        flyUpBallotAgree(memberRole);
                        MessagePusher.pushMessage(memberRole, new RespMsg("你开启了固定队伍特权1，参与通天塔#R投票#n自动通过"));

                    }
                }
            }
        }

    }
    private int getNeedGold(int flyUpCount) {
        if (flyUpCount <= 5) {
            return 90;
        } else {
            return 180;
        }
    }

    /**获得投票结果*/
    private RespBallotResult getRespBallotResult(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Map<Integer, Short> ballotResults = null;
        if (team.isLeader(role.getRoleId())) {
            TowerTeamFlyUpConfirm confirm = (TowerTeamFlyUpConfirm)role.getConfirm();
            ballotResults = confirm.getBallotResults();
        } else {
            Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
            TowerTeamFlyUpConfirm confirm = (TowerTeamFlyUpConfirm)leaderRole.getConfirm();
            ballotResults = confirm.getBallotResults();
        }

        ArrayList<BallotInfo> ballotInfos = new ArrayList<>();
        for (Map.Entry<Integer, Short> entry : ballotResults.entrySet()) {
            Role memberRole = SpringUtils.getRoleService().getOnlinePlayer(entry.getKey());
            if (memberRole == null) {continue;}
            BallotInfo ballotInfo = new BallotInfo();
            ballotInfo.setName(memberRole.getName());
            ballotInfo.setType(entry.getValue());
            ballotInfos.add(ballotInfo);
        }
        RespBallotResult respBallotResult = new RespBallotResult();
        respBallotResult.setMeTime((short) -1);
        respBallotResult.setResultList(ballotInfos);

        return respBallotResult;
    }

    /**飞升检测*/
    private String checkFlyUp(Role role, int flyUpCount) {
        String check = checkEnterNextLayer(role);
        if (check != null) {
            return check;
        }

        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            /**判断是否有队员飞升后会跨越突破层*/
            String names = teamService.checkMember(team, (Role memberRole) -> {
                RoleTowerData roleTowerData = memberRole.getActivity().getRoleTowerData();
                return roleTowerData.isInBreakStage() == false && roleTowerData.getCurrentLayer() + flyUpCount > role.getLevel();
            });
            if (names != null) {
                return MessageFormat.format(TEAM_FLY_UP_BEYOND_REFINE, names);
            }
        } else {
            RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
            if (roleTowerData.isInBreakStage() == false && roleTowerData.getCurrentLayer() + flyUpCount > role.getLevel()) {
                return FLY_UP_BEYOND_REFINE;
            }
        }
        return null;
    }

    /**确认消耗金钱或者元宝进行飞升*/
    public void confirmFlyUp(Role role) {
        TowerFlyUpConfirm towerFlyUpConfirm = (TowerFlyUpConfirm)role.getConfirm();
        int flyUpCount = towerFlyUpConfirm.getFlyUpCount();
        byte flyUpType = towerFlyUpConfirm.getFlyUpType();

        String check = checkFlyUp(role, flyUpCount);
        if (check != null) {
            RespMsg respMsg = new RespMsg(check.replace(Const.LEAVE_BUTTON, ""));
            MessagePusher.pushMessage(role, respMsg);
            return ;
        }

        if (isFlyUpEnoughResource(role, flyUpType, flyUpCount) == false) {
            String resourceName = (flyUpType == Const.FLY_UP_TYPE_USING_MONEY ? Const.MONEY_NAME : Const.GOLD_NAME);
            MessagePusher.pushMessage(role, new RespMsg(MessageFormat.format(Const.ROLE_RESOURCE_NOT_ENOUGH, resourceName)));
            return ;
        }

        substractFlyUpResource(role, flyUpType, flyUpCount);

        doFlyUp(role, flyUpCount);
    }

    /**进行飞升操作*/
    private void doFlyUp(Role role, int flyUpCount) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        /**超过最大层数时，赋值为最大层数*/
        int toLayer = roleTowerData.getCurrentLayer() + flyUpCount;
        if (toLayer > MAX_LAYER) {
            toLayer = MAX_LAYER;
        }

        if (teamService.isInTeam(role)) {
            Team team = teamService.getTeam(role.getRoleId());
            /**暂离玩家进行离队处理*/
            notInTeamLeave(team);

            int finalToLevel = toLayer;
            teamService.memberHandle(team, (Role memberRole) -> enterLayer(memberRole, finalToLevel));
        } else {
            enterLayer(role, toLayer);
        }
    }

    public TowerMirrorRankRecord getXinJunRankData(Role role, int npcId) {
        return getXinJunRankData(role, npcId, role.getPos().getMapId());
    }

    /**获得通天塔对应层数星君对应的排行榜数据*/
    public TowerMirrorRankRecord getXinJunRankData(Role role, int npcId, int mapId) {
        if (isInTower(mapId) == false) {
            return null;
        }

        if (role.getActivity().getRoleTowerData() != null) {
            int layer = role.getActivity().getRoleTowerData().getCurrentLayer();
            return SpringUtils.getBean(TowerMirrorRankHandler.class).getRecord(layer, npcId);
        }

        return null;
    }

    /**添加通天塔排行榜数据*/
    public void addTowerRankData(Role role) {
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        /**当前层未通过时，返回*/
        if (roleTowerData.isCurrentFinish() == false) {return ;}
        /**突破次数没有达到要求时，返回*/
        if (roleTowerData.getCurrentLayer() < role.getLevel() + RANK_MIN_BREAK_COUNT) {return ;}

        SpringUtils.getBean(TowerMirrorRankHandler.class).update(role, XIN_JUN_NPCID_LIST);
    }

    /**飞升投票不同意*/
    public void flyUpBallotDisagree(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        TowerTeamFlyUpConfirm teamFlyUpConfirm = (TowerTeamFlyUpConfirm)leaderRole.getConfirm();
        Map<Integer, Short> ballotResults = teamFlyUpConfirm.getBallotResults();
        ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_DISAGREE);

        RespBallotResult respBallotResult = getRespBallotResult(role);
        teamService.pushMessageToTeam(team, respBallotResult);
    }


    /**飞升投票同意*/
    public void flyUpBallotAgree(Role role) {
        Team team = teamService.getTeam(role.getRoleId());
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        TowerTeamFlyUpConfirm teamFlyUpConfirm = (TowerTeamFlyUpConfirm)leaderRole.getConfirm();

        byte flyUpType = teamFlyUpConfirm.getFlyUpType();
        int flyUpCount = teamFlyUpConfirm.getFlyUpCount();
        /**判断是否有足够的金钱或元宝*/
        if (isFlyUpEnoughResource(role, flyUpType, flyUpCount) == false) {
            String resourceName = (flyUpType == Const.FLY_UP_TYPE_USING_MONEY ? Const.MONEY_NAME : Const.GOLD_NAME);
            MessagePusher.pushMessage(role, new RespMsg(MessageFormat.format(Const.ROLE_RESOURCE_NOT_ENOUGH, resourceName)));
            return ;
        }

        Map<Integer, Short> ballotResults = teamFlyUpConfirm.getBallotResults();
        ballotResults.put(role.getRoleId(), Const.BALLOT_TYPE_AGREEN);

        RespBallotResult respBallotResult = getRespBallotResult(role);
        teamService.pushMessageToTeam(team, respBallotResult);


        /**所有人已经同意，则开始扣除*/
        boolean allAgree = true;
        for (short result : ballotResults.values()) {
            if (result != Const.BALLOT_TYPE_AGREEN) {
                allAgree = false;
            }
        }

        if (allAgree) {
            /**此时再检测下所有成员有足够的金钱或元宝*/
            String names = teamService.checkMember(team, (Role memberRole) -> isFlyUpEnoughResource(memberRole, flyUpType, flyUpCount) == false);
            if (names != null) {
                String resourceName = (flyUpType == Const.FLY_UP_TYPE_USING_MONEY ? Const.MONEY_NAME : Const.GOLD_NAME);
                teamService.pushMessageToTeam(team, new RespMsg(MessageFormat.format(TEAM_FLY_UP_RESOURCE_NOT_ENOUGH, resourceName)));
            } else {
                /**真正开始扣除*/
                teamService.memberHandle(team, (Role memberRole) -> {substractFlyUpResource(memberRole, flyUpType, flyUpCount);});
                /**进行飞升*/
                doFlyUp(leaderRole, flyUpCount);
            }
        }
    }

    /**判断是否有足够的金钱或元宝进行飞升*/
    private boolean isFlyUpEnoughResource(Role role, byte flyUpType, int flyUpCount) {
        if (flyUpType == Const.FLY_UP_TYPE_USING_MONEY) {
            int needMoney = getNeedMoney(flyUpCount);
            /**检测金钱是否满足*/
            if (role.getMoney() >= needMoney) {
                return true;
            }
        } else {
            int needGold = getNeedGold(flyUpCount);
            /**检测元宝是否满足*/
            if (role.getGold() >= needGold) {
                return true;
            }
        }

        return false;
    }

    /**扣除飞升的金钱或元宝*/
    private void substractFlyUpResource(Role role, byte flyUpType, int flyUpCount) {
        if (flyUpType == Const.FLY_UP_TYPE_USING_MONEY) {
            int needMoney = getNeedMoney(flyUpCount);
            /**扣除*/
            SpringUtils.getRoleService().subtractMoney(role, needMoney);
        } else {
            int needGold = getNeedGold(flyUpCount);
            /**扣除*/
            SpringUtils.getRoleService().subtractGold(role, needGold, Reason.TOWER_FLY_UP);
        }
    }

    /**是否可以归队*/
    public boolean isBackToTeam(Team team, Role memberRole) {
        /**队长在通天塔时，队员也需要在与队长同一层时才能归队*/
        Role leaderRole = SpringUtils.getRoleService().getOnlinePlayer(team.getLeaderUid());
        if (isInTower(leaderRole)) {
            if (isInTower(memberRole) == false) {
                MessagePusher.pushMessage(memberRole, new RespMsg(RETURN_TEAM_NOT_IN_SAME_LAYER));
                return false;
            }

            if (leaderRole.getActivity().getRoleTowerData().getCurrentLayer() != memberRole.getActivity().getRoleTowerData().getCurrentLayer()) {
                MessagePusher.pushMessage(memberRole, new RespMsg(RETURN_TEAM_NOT_IN_SAME_LAYER));
                return false;
            }
        }
        return true;
    }

    /**改变奖励类型*/
    public String confirmChangeRewardType(Role role, NPC npc) {
        /**未接任务*/
        if (!isAcceptedTask(role)) {
            return NOT_ACCEPTED;
        }

        /**突破阶段时不可改变*/
        if (role.getActivity().getRoleTowerData().isInBreakStage()) {
            return CHANGE_REWARD_IN_BREAK_STAGE;
        }

        String msg = null;
        if (role.getActivity().getRoleTowerData().getRewardType() == RoleTowerData.REWARD_EXP) {
            msg = MessageFormat.format(CHANGE_REWARD_TIP, Const.EXP_NAME, Const.DAOHANG_NAME);
        } else {
            msg = MessageFormat.format(CHANGE_REWARD_TIP, Const.DAOHANG_NAME, Const.EXP_NAME);
        }
        role.setConfirm(new TowerChangeRewardConfirm());
        RespConfirm respConfirm = new RespConfirm();
        respConfirm.setTips(msg);
        respConfirm.setConfirm_type("");
        MessagePusher.pushMessage(role, respConfirm);

        return null;
    }

    /**改变奖励类型*/
    public void confirmChangeRewardType(Role role) {
        String tips ="当前#R通天塔#n任务获得的奖励类型成功修改为#R{0}#n。";
        if (role.getActivity().getRoleTowerData().getRewardType() == RoleTowerData.REWARD_EXP) {
            role.getActivity().getRoleTowerData().setRewardType(RoleTowerData.REWARD_DAOHANG);
            tips =MessageFormat.format(tips,"道行");
        } else {
            role.getActivity().getRoleTowerData().setRewardType(RoleTowerData.REWARD_EXP);
            tips =MessageFormat.format(tips,"经验");
        }
        MessagePusher.pushMessage(role,new RespNotifyMiscEx(tips));
        TaskSet taskSet = getTaskSetByType(role);
        taskService.pushTaskInfo(role, getTaskInfo(role,taskSet));
        pushTowerInfo(role);
        role.save();
    }

    /**请求放弃任务*/
    public void requestGiveUpTask(Role role) {
        if (isInTower(role)) {
            MessagePusher.pushMessage(role, new RespMsg(NOT_GIVE_UP_TASK_TIP_IN_TOWER));
            return ;
        }

        if (!isAcceptedTask(role)) {
            MessagePusher.pushMessage(role, new RespMsg(NOT_ACCEPTED_TOWER_TASK));
            return ;
        }

        String msg = null;
        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (roleTowerData.isInBreakStage()) {
            msg = GIVE_UP_TASK_IN_BREAK_STAGE;
        } else {
            msg = GIVE_UP_TASK_IN_REFINE_STAGE;
        }
        role.setConfirm(new GiveUpTaskConfirm(getTaskSetByType(role).getTaskName()));

        RespConfirm respConfirm = new RespConfirm();
        respConfirm.setTips(msg);
        respConfirm.setConfirm_type("");
        MessagePusher.pushMessage(role, respConfirm);
    }

    /**确认放弃任务*/
    public void confirmGiveUpTask(Role role) {
        if (isInTower(role)) {
            MessagePusher.pushMessage(role, new RespMsg(NOT_GIVE_UP_TASK_TIP_IN_TOWER));
            return ;
        }

        TaskSet taskSet = getTaskSetByType(role);
        if (taskSet == null) {
            MessagePusher.pushMessage(role, new RespMsg(NOT_ACCEPTED_TOWER_TASK));
            return ;
        }

        RoleTowerData roleTowerData = role.getActivity().getRoleTowerData();
        if (roleTowerData != null) {
            /**增加次数*/
            addActivityFinishCount(role, taskSet);
        }
        deleteTaskForSingle(role, taskSet);
    }

    @Override
    protected void doBeforeDelete(Role role, TaskSet taskSet) {

    }

    @Override
    protected void doAfterDelete(Role role, TaskSet taskSet) {

    }

    @Override
    public boolean isCreateNpcForFight(TaskSet taskSet) {
        return false;
    }

    public void sendNpcContent(Role role, NPC bossNpc) {
        String content = getNpcContent(role, bossNpc);
        SpringUtils.getNpcService().sendNpcContent(role, bossNpc, content);
    }

    /**选择进入通天塔*/
    public void chooseEnterTower(Role role, NPC npc) {
        String content = doChooseEnterTower(role, npc);
        if (content != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, content);
        }
    }

    public void changeRewardType(Role role, NPC npc) {
        String content = confirmChangeRewardType(role, npc);
        if (content != null) {
            SpringUtils.getNpcService().sendNpcContent(role, npc, content);
        }
    }
}
